; Programa 'sudetis.asm' (22 variantas)
; Programa sudeda du dvejetainius skaicius irasytus duomenu failuose
; ------------------------------------------------------------------
LOCALS @@ ; Lokalios zymes prasideda @@
.MODEL small ; Atminties modelis:
; 64K kodui ir 64K duomenims
.STACK 256
.DATA
kur DW 0
ilgis1 DW 0
ilgis2 DW 0
ilgis3 DW 0
handle DW 0
error DB "Skaitant is failo ivyko klaida"
errorLen = $-error ; Eilutes ilgis gaunamas is einamojo adreso ($) atemus jos pradzios adresa
Helpmsg DB "Programa sudeda du dvejetainius skaicius, kurie irasyti i duomenu failus ir rezulta iraso i rezultatu faila",0dh,0ah,"Programos parametrai perduodami taip:",0dh,0ah,"sudetis4 duomenu_failas1 duomenu_failas2 rezultatu_failas"
HelpLen = $-Helpmsg ; Eilutes ilgis gaunamas is einamojo adreso ($) atemus jos pradzios adresa
.DATA? ; Neinicializuojami duomenys
fname1 DB 20h DUP(?) ;input1
fname2 DB 20h DUP(?) ;input2
fname3 DB 20h DUP(?) ;output
fbuf1 DB 1000h DUP(?)  ; Skaitymo buferis
fbuf2 DB 1000h DUP(?) ; Skaitymo buferis 2
fbuf3 DB 1000h DUP(?) ; Rasymo buferis

.CODE
Strt:
mov bl, [ds: 80h] ; Parametru eilutes ilgis
xor bh, bh
mov byte ptr [bx+81h], ' ' ; Idedam po parametru eilutes tarpa

mov cx, ds ; Issisaugom psp segmenta i cx

mov ax,@data
mov ds,ax    

; Irasom i atminti duomenu ir rezultatu failu pavadinimus
cld
mov si, 82h
mov [kur], OFFSET fname1
call Parametrai
call Help
mov [kur], OFFSET fname2
call Parametrai
mov [kur], OFFSET fname3
call Parametrai

mov dx, OFFSET fname1
mov [kur], OFFSET fbuf1
call ReadFile
mov [ilgis1], cx

mov dx, OFFSET fname2
mov [kur], OFFSET fbuf2
call ReadFile
mov [ilgis2], cx

call Sudet
call WriteFile

;isvesti rezultata i ekrana
;mov dx, OFFSET fbuf3
;mov cx, [ilgis3]
;call PrintBuf

pabaiga:
mov ax,04C00h
int 21h ; int 21,4C - programos pabaiga


;-------------------------------------------------------------------
; Parametrai - writes one of the parameters into memory
; IN
; si - offset of the parameter start in psp
; [kur] - offset of output buffer
; OUT
; output buffer - the parameter
;-------------------------------------------------------------------
Parametrai PROC
push bx
push ax
mov bx, [kur]
@@skaityti:
push ds
mov ds, cx
lodsb
pop ds
cmp al, ' '
jz @@naikinti
mov [bx], al
inc bx
jmp @@skaityti
@@naikinti:
push ds
mov ds, cx
lodsb
pop ds
cmp al, ' '
jnz @@baigti
jmp @@naikinti
@@baigti:
dec si
mov byte ptr [bx], 0
pop ax
pop bx
ret
Parametrai ENDP

;-------------------------------------------------------------------
; Help - checks if it is asked for help
; IN
; [fname]
;-------------------------------------------------------------------
Help PROC
cmp [fname1], '/'
jnz @@baigti
cmp [fname1+1], '?'
jnz @@baigti
mov dx, OFFSET Helpmsg
mov cx, (HelpLen)
call PrintBuf
jmp pabaiga
@@baigti:
ret
Help ENDP

;-------------------------------------------------------------------
; Sudet - calculates sum of two binary numbers stored in fbuf1 and fbuf2
; IN
; fbuf1 - the first number
; fbuf2 - the second number
; [ilgis1] - length of the first number
; [ilgis2] - length of the second number
; OUT
; fbuf3 - the sum of the numbers
; [ilgis3] - length of the sum
;-------------------------------------------------------------------
Sudet PROC
push 0
xor bx, bx
mov cx, [ilgis1]
cmp cx, [ilgis2]
ja @@toliau
mov cx, [ilgis2]
@@toliau:
inc cx
mov [ilgis3], cx
dec cx
@@kartoti:
inc bx
push bx
xor al, al
sub bx, [ilgis1]
neg bx
cmp bx, 0
jl @@trumpas
mov al, [fbuf1+bx]
sub al, '0'
@@trumpas:
pop bx
push bx
sub bx, [ilgis2]
neg bx
cmp bx, 0
jl @@trumpas2
mov dl, [fbuf2+bx]
sub dl, '0'
add al, dl
@@trumpas2:
pop bx
pop dx
add al, dl
xor dx, dx
cmp al, 2
jb @@nulisminty
sub al, 2
inc dx
@@nulisminty:
push dx
add al, '0'
push bx
sub bx, [ilgis3]
neg bx
mov [fbuf3+bx], al
pop bx
loop @@kartoti

mov [fbuf3], ' '
pop dx
cmp dx, 0
jz @@nieko
add dl, '0'
mov [fbuf3], dl
@@nieko:    
ret
Sudet ENDP

;-------------------------------------------------------------------
; ReadFile - reads data from file
; IN
; dx - offset of filename
; [kur] - offset of output buffer
; OUT
; cx - number of symbols read
; output buffer - data
;-------------------------------------------------------------------
ReadFile PROC
mov [Handle], 0    
mov ax,3d00h
int 21h
jc @@Exit
mov [handle],ax ; Issaugoti deskriptoriu
mov bx,ax
push 0
@@Loop:
mov ah,3fh
mov dx, [kur]
pop cx
add dx, cx
push cx
mov cx,100h
int 21h ; Skaityti faila
jc @@Exit
or ax,ax
jz @@Exit ; EOF - failo pabaiga
pop cx
add cx, ax
push cx
jmp SHORT @@Loop

@@Exit:
pop cx
;Duomenu atspausdinimas
;mov dx, [kur]
;call PrintBuf
mov bx,[Handle]
or bx,bx
jz @@NoClose
mov ah,3Eh
int 21h ; Uzdaryti faila
@@NoClose:
or bx, bx
jnz @@NoError
mov cx,(errorLen)
mov dx,OFFSET error
call PrintBuf ; Atspausdiname klaidos pranesima  
jmp Pabaiga
@@NoError:
ret
ReadFile ENDP

;-------------------------------------------------------------------
; writes results from fbuf3 to file fname3
;-------------------------------------------------------------------
WriteFile PROC
mov dx, OFFSET fname3
mov ah, 3Ch
mov cx, 100000b
int 21h ; sukurti faila
jc @@nesukurtas
mov bx, ax
mov ah, 40h
mov cx, [ilgis3]
mov dx, OFFSET fbuf3
int 21h ; irasyti rezultata i faila
mov ah, 3Eh
int 21h ; Uzdaryti faila
@@nesukurtas:    
ret
WriteFile ENDP

;-------------------------------------------------------------------
; PrintBuf - prints char buffer to STDOUT
; IN
; cx - char count
; dx - buf
;-------------------------------------------------------------------
PrintBuf PROC
push ax 
push bx 
mov ah,40h
mov bx,1
int 21h 
pop bx 
pop ax
ret
PrintBuf ENDP
END Strt